<?php
declare (strict_types = 1);
namespace app\command;
use app\chat\Chat;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
use fast\Redis;
use fast\Mysqlasync;
$basedir = dirname(__FILE__);
class WebsocketServer extends Command
{
    protected  $dbcofig = [
            'host'=>'127.0.0.1',
            "port"=>3306,
            "user"=>"root",
            "password"=>"123456",
            "database"=>"testwyt",
            "charset"=>'utf8',
//        'timeout' => '建立连接超时时间',
//        'strict_type' => false, //开启严格模式，query方法返回的数据也将转为强类型
//        'fetch_mode' => true, //开启fetch模
        ];

    protected function configure()
    {
        // 指令配置
        $this->setName('scoket')
            ->setDescription('the scoket command');
    }

    protected function execute(Input $input, Output $output)
    {
        //创建WebSocket Server对象，监听0.0.0.0:9502端口
        $ws = new \swoole_websocket_server('0.0.0.0', 9501);
        $ws->set([
            'worker_num'    =>4,//开启2个worker进程
//            'daemonize' => true, //守护进程(true/false) 1, //关闭打印或调试数据
//            'log_file'   => $basedir.'/data/log/swoole.log',
            'heartbeat_check_interval' => 30, //心跳检测 每隔多少秒，遍历一遍所有的连接
            'heartbeat_idle_time' => 65,      //心跳检测 最大闲置时间，超时触发close并关闭
            'max_request' => 10, //每个worker进程 max_request设置为4次
            'task_worker_num' => 4, //开启4个task进程（必须启用task和finish回调）
//            'max_conn'	    =>1000,
//            'pipe_buffer_size' => 2 * 1024 *1024,
//            'buffer_output_size' => 2 * 1024 *1024,
//            'socket_buffer_size' => 2 * 1024 *1024,
//            'dispatch_mode' => 4, //数据包分发策略 - IP分配（ppt介绍）
        ]);

        $ws->on('Start', function ($ws) {
            echo "#### 启动服务 ####" . PHP_EOL;
        });
        //监听WebSocket连接打开事件
        $ws->on('Open', function ($ws, $request) {
            $this -> onOpen($ws, $request);
        });

        //监听WebSocket消息事件
        $ws->on('Message', function ($ws, $frame) {
//            $data = $frame->data;
//            foreach($map as $fd){
//                $ws->push($fd , $data);//循环广播
//            }
            $this -> onMessage($ws, $frame);
        });
        $ws->on('Task', function ($ws,$task_id,$worker_id,$data) {

        });
        $ws->on('Finish', function ($ws,$task_id,$data) {

        });
        //监听WebSocket连接关闭事件
        $ws->on('Close', function ($ws, $fd) {
            $this -> onClose($ws, $fd);
        });
//        $ws->on('shutdown',function(){
//            echo "Server 正常结束\n";
//            unlink("/data/log/swoole.log");
//            $res=system("rm -rf /var/www/swoole/swoole_chat/upload");
//            echo $res;
//        });
        $ws->start();
    }


    protected function onOpen($ws, $request){
        $fd = $request->fd;
        echo "链接成功{$fd}\n" . PHP_EOL;
        $getArr = $request->get;
        $info=$ws->getClientInfo($request->fd);
        echo "{$info['remote_ip']}[{$info['remote_port']}] connect...\n";
        var_dump($getArr);
        //判断token是否为空
        if(!empty($getArr) && isset($getArr['token']) && !empty($getArr['token'])){
            if ($getArr['token'] == "websocket_kefu") {   //客服连接config('queue.websocket_kefu')
                return Redis::set($getArr['token'].$fd, $fd);   //缓存 客服标识 => fd
            } else {    //用户连接
                $cacheRst = Redis::get($getArr['token']);
                var_dump($cacheRst);
                if ($cacheRst){
                    if (!is_array($cacheRst)){
                        $cacheRst = json_decode($cacheRst,true);
                    }
                    if (array_key_exists('openId', $cacheRst)){
                        return Redis::set($cacheRst['openId'], $fd);   //缓存openid => fd
                    }
                }
               echo  Redis::get($cacheRst['openId']);
            }
        }
        return $ws->close($fd);
    }
    private function sendTo1($ws,$data){
        $tofd=(int)$data['tofd'];
        $fd=(int)$data['fd'];
        $type=(int)$data['type'];
        $data=json_encode($data);
        if($tofd==-1){//群发
//            foreach($table as $key =>  $val){
//                $ws->push($key,$data);
//            }
        }else{
            $ws->push($tofd,$data);
            if($type!=2&&$type!=1){
                $ws->push($fd,$data);
            }
        }
    }

    protected function onMessage($ws, $frame){
        $swoole_mysql = new \Swoole\Coroutine\MySQL();
        $swoole_mysql->connect($this->dbcofig);

        $res = $swoole_mysql->query('select * from fa_user');
        if($res === false) {
            return;
        }
        foreach ($res as $value) {
            echo $value['id'];
        }

//        $info=$ws->getClientInfo($frame->fd);
//        echo "Message: {$frame->data}\n";
//        $data = json_decode($frame->data,true);
//        $data['fd']=$frame->fd;
//        $data=array_merge($data,$info);
//
////        $Chat = new Chat($frame->fd,$data);
//        $list=[];
//        switch ((int)$data['type']){
//            case 1://新连接
//            case 2://连接建立
//                $res=$data;
//                $res['type']=1;
//                    $res['tofd']=-1;
//                    $this ->sendTo1($ws,$res);
//            echo "TO";var_dump($data);
//                    $list=[];
////                var_dump($res);
//                $res['type']=2;
////                    $kuserlist = $Chat -> kuserlist();
////                    foreach($kuserlist as $key =>$val){
////                        $list[$key]=$val;
////                    }
//                    $res['list']=$list;
////                    var_dump($res);
//                $this ->sendTo1($ws,$res);
////            $arr = ['name'=>'starsea','info'=>['sex'=>'男','age'=>23]];
////
//            $userinfo = $data['userInfo'];
//                Redis::set($frame->fd,json_encode($userinfo));
////                $table->set($frame->fd,['nickname'   =>$data['userInfo']['nickname'],                   'avatar'   =>$data['userInfo']['avatar']]);
//                break;
//            case 4://消息
//            case 6://视频数据
//            case 7://音频数据
//                $res=$data;
//                var_dump($res);
//                $res['userInfo']= Redis::get($frame->fd);
////                var_dump($res['userInfo']);
//                $this ->sendTo1($ws,$res);
//                break;
//            default:
//        }
//        $url = $request_data["url"];
////        var_dump($request_data);
//        if($url == "heartbeat"){
//            $data = [
//                'url'=> $url,
//                'msglist'=>'123456'
//            ];
//            $result = chatBack(200,"发送消息",$data);
////            $result= "server: {$frame->data}";
//        }else{
//            $Chat = new Chat($frame->fd,$request_data);
//            $result =  $Chat -> $url();
//        }
//        $ws->push($frame->fd, $result);
    }


    protected function onClose($ws, $fd)
    {
//        echo "client-{$fd} is closed\n";
//        Redis::del('person'.$fd);
//        Redis::sRem('online',$fd);
//        $ws ->push($fd,"有人下线\n");
        $info=$ws->getClientInfo($fd);
//        global $table;
//        $table->del($fd);
//        $info['type']=3;
//        $info['fd']=$fd;
//        $info['tofd']=-1;
//        $info['userInfo']=$table->get($fd);
//        $this -> sendTo($ws,$info);
        echo "{$info['remote_ip']}[{$info['remote_port']}] close\n";
    }

    private function sendTo($ws,$data=array()){
        var_dump($data);
//        $id = 1;
//        go(function () use($id){
//            $mysql = new \Swoole\Coroutine\MySQL();
//            //connect
//            $mysql->connect($this->dbconfig);
//            $sql = "select * from fa_user where id = ".$id;
//            $res = $mysql->query($sql);
//            if($res === false){
//                var_dump("error");
//            }
//            var_dump($res);
//            $mysql->close();
//        });
    }
}
